package cn.swpu.blog.service.impl;

import cn.swpu.blog.dao.BlogCategoryInfoMapper;
import cn.swpu.blog.dao.BlogContentMapper;
import cn.swpu.blog.dao.BlogMapper;
import cn.swpu.blog.dao.BlogTagInfoMapper;
import cn.swpu.blog.dto.UpdateTimeDto;
import cn.swpu.blog.entity.*;
import cn.swpu.blog.exception.BlogNotFoundException;
import cn.swpu.blog.from.SaveBlogFrom;
import cn.swpu.blog.from.UpdateBlogFrom;
import cn.swpu.blog.service.IBlogService;
import cn.swpu.blog.vo.BlogDetailVo;
import cn.swpu.blog.vo.ResponseVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author 冰翔
 * @Date Created in 10:37 下午 2020/12/10
 */
@Service
@Slf4j
public class BlogServiceImpl implements IBlogService {

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private BlogContentMapper blogContentMapper;

    @Autowired
    private BlogCategoryInfoMapper blogCategoryInfoMapper;

    @Autowired
    private BlogTagInfoMapper blogTagInfoMapper;

    @Override
    public ResponseVo<BlogDetailVo> queryBlogDetail(Integer blogId) {

        //根据ID从blog表和blog_content查询出对应数据
        Blog blog = blogMapper.selectByPrimaryKey(blogId);
        BlogContent blogContent = blogContentMapper.selectByBlogId(blogId);

        BlogDetailVo blogDetailVo = new BlogDetailVo();

        BeanUtils.copyProperties(blog, blogDetailVo);
        blogDetailVo.setContent(blogContent.getContent());

        //查询出category
        int categoryId = blogCategoryInfoMapper.selectByBlogId2CategoryId(blogId);
        blogDetailVo.setCategoryId(categoryId);

        //查询出tags List<Integer>
        List<Integer> tagList = blogTagInfoMapper.selectByBlogId(blogId);
        blogDetailVo.setTags(tagList);

        return ResponseVo.success(blogDetailVo);
    }

    @Override
    public ResponseVo<PageInfo> pageBlog(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize,"is_top DESC");

        List<Blog> blogList = blogMapper.selectAll();


        PageInfo pageInfo = new PageInfo<>(blogList);
        pageInfo.setList(blogList);

        return ResponseVo.success(pageInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVo<Map<String, Integer>> saveBlog(SaveBlogFrom from) {
        Blog blog = new Blog();
        BlogContent blogContent = new BlogContent();

        BeanUtils.copyProperties(from, blog);
        BeanUtils.copyProperties(from, blogContent);

        //from中没有的blog属性 id（插入数据库获得） browseCount初始值设置未0 wordCount计算或得
        blog.setBrowseCount(0);

        //简单的统计了字符的个数，非常不准确
        //TODO 更加优雅的统计单词数
        blog.setWordCount(from.getContent().length());

        blogMapper.insert(blog);

        //from中没有的blogContent属性 blogId 插入blog后返回的属性 id无所谓，好像没有用到
        blogContent.setBlogId(blog.getBlogId());
        blogContentMapper.insert(blogContent);

        //存储category 只有一条Integer
        if (from.getCategoryId() != null) {
            BlogCategoryInfo blogCategoryInfo = new BlogCategoryInfo();
            blogCategoryInfo.setBlogId(blog.getBlogId());
            blogCategoryInfo.setCategoryId(from.getCategoryId());

            blogCategoryInfoMapper.insert(blogCategoryInfo);
        }

        List<BlogTagInfo> blogTagInfoList = new ArrayList<>();

        //TODO 用Stream流处理
        //存储tag 可能有很多List<Integer>
        if (from.getTags() != null) {
            for (Integer tagId : from.getTags()) {
                BlogTagInfo blogTagInfo = new BlogTagInfo();
                blogTagInfo.setBlogId(blog.getBlogId());
                blogTagInfo.setTagId(tagId);
                blogTagInfoList.add(blogTagInfo);
            }
        }

        blogTagInfoMapper.insertByList(blogTagInfoList);

        //TODO 未判断categoryId tagId是否有效
        Map<String, Integer> map = new HashMap<>(1);
        map.put("blogId", blog.getBlogId());
        return ResponseVo.success(map);
    }

    @Override
    public ResponseVo setTop(Integer blogId) {
        int result = blogMapper.setTop(blogId);
        if (result != 1) {
            throw new BlogNotFoundException("置顶失败");
        }
        return ResponseVo.success();
    }

    @Override
    public ResponseVo cancelTop(Integer blogId) {
        int result = blogMapper.cancelTop(blogId);
        if (result != 1) {
            throw new BlogNotFoundException("取消置顶失败");
        }
        return ResponseVo.success();
    }

    @Override
    public ResponseVo deleteBlog(Integer blogId) {
        int result = blogMapper.deleteByPrimaryKey(blogId);
        if (result != 1) {
            throw new BlogNotFoundException("删除失败");
        }
        return ResponseVo.success();
    }

    @Override
    public ResponseVo updateBlog(UpdateBlogFrom from) {
        //获取博客创建时间
        Date createDate = blogMapper.selectDateByBlogId(from.getBlogId());
        int browseCount = blogMapper.selectBrowseCountByBlogId(from.getBlogId());

        //删除原来的博客，并存储新内容
        blogMapper.deleteByPrimaryKey(from.getBlogId());

        //插入blog
        Blog blog = new Blog();
        BeanUtils.copyProperties(from, blog);
        blog.setBrowseCount(browseCount);
        blog.setCreateTime(createDate);
        blog.setUpdateTime(new Date(System.currentTimeMillis()));
        blog.setWordCount(from.getContent().length());

        blogMapper.insertAgain(blog);

        //插入Content
        BlogContent blogContent = new BlogContent();
        BeanUtils.copyProperties(from, blogContent);
        blogContentMapper.insert(blogContent);

        //存储category 只有一条Integer
        if (from.getCategoryId() != null) {
            BlogCategoryInfo blogCategoryInfo = new BlogCategoryInfo();
            blogCategoryInfo.setBlogId(blog.getBlogId());
            blogCategoryInfo.setCategoryId(from.getCategoryId());

            blogCategoryInfoMapper.insert(blogCategoryInfo);
        }

        List<BlogTagInfo> blogTagInfoList = new ArrayList<>();

        //TODO 用Stream流处理
        //存储tag 可能有很多List<Integer>
        if (from.getTags() != null) {
            for (Integer tagId : from.getTags()) {
                BlogTagInfo blogTagInfo = new BlogTagInfo();
                blogTagInfo.setBlogId(blog.getBlogId());
                blogTagInfo.setTagId(tagId);
                blogTagInfoList.add(blogTagInfo);
            }
        }

        blogTagInfoMapper.insertByList(blogTagInfoList);
        return ResponseVo.success();
    }

}
